/*--------------------------------------------------------------------------
    This source file is part of Abraxas Game Engine
    For the latest info, see http://code.google.com/abraxasge/
    Copyright (C) 2009, Andrew LeRoy <aleroy@member.igda.org>
    ---

    This program is free software; you can redistribute it and/or
    modify it under the terms of the GNU General Public License
    as published by the Free Software Foundation; either version 2
    of the License, or (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 51 Franklin Street, Fifth Floor,
    Boston, MA  02110-1301, USA.
--------------------------------------------------------------------------*/
#ifndef _Abx_GraphicsSystem_hpp_
#define _Abx_GraphicsSystem_hpp_

#include "AbxPrerequisites.hpp"

namespace Abx
{
    /**
     * An options structure which stores data for identifing
     * and initializing the specific plugin subclass.
     */
    struct _AbxExport GraphicsSystemOptions
    {
        String typeName;
        String description;
    };


    /**
     * Provides methods to create & destroy a GraphicsSystem instance
     * as well as a parameters structure (which stores data for
     * identifing and initializing the specific plugin subclass).
     */
    class _AbxExport GraphicsSystemFactory
    {
    public:   // C'STOR / D'STOR
        GraphicsSystemFactory() : optionsInit_(true) { }
        virtual ~GraphicsSystemFactory() { }

        virtual GraphicsSystemOptions const& getOptions() const
        {
            if (optionsInit_)
            {
                initOptions();
                optionsInit_ = false;
            }
            return options_;
        }
        virtual GraphicsSystem* createInstance(String const& name) = 0;
        virtual void destroyInstance(GraphicsSystem* instance) = 0;

    protected:
        virtual void initOptions() const = 0;

      protected:
        mutable GraphicsSystemOptions  options_;
        mutable bool                   optionsInit_;
    };
    
    
    class _AbxExport GraphicsSystem
    {
    public: // TYPES
        typedef GraphicsSystemOptions options_type;
        typedef GraphicsSystemFactory factory_type;
    
    public:   // C'STOR / D'STOR
        GraphicsSystem(String const& name) { }
        virtual ~GraphicsSystem() { }

    public: // FUNCTIONS
        virtual String const& getName() const = 0;
        virtual String const& getTypeName() const = 0;

    protected: // DATA
        String name_;
    };
    


    class _AbxExport DefaultGraphicsSystemFactory : public GraphicsSystemFactory
    {
    public:   // C'STOR / D'STOR
        DefaultGraphicsSystemFactory();
        virtual ~DefaultGraphicsSystemFactory();

    public: // FUNCTIONS
        virtual GraphicsSystem* createInstance(String const& name);
        virtual void destroyInstance(GraphicsSystem* instance);

    protected:
        virtual void initOptions() const;

    public:
        static String const FACTORY_TYPE;
    };

    class _AbxExport DefaultGraphicsSystem : public GraphicsSystem
    {
        friend class DefaultGraphicsSystemFactory;

    public:   // TYPES
        typedef GraphicsSystemOptions options_type;
        typedef DefaultGraphicsSystemFactory factory_type;

    public:   // C'STOR / D'STOR
        DefaultGraphicsSystem(String const& name);
        virtual ~DefaultGraphicsSystem();

    public: // FUNCTIONS
        virtual String const& getName() const;
        virtual String const& getTypeName() const;

    protected: // DATA
        String typeName_;
    };
} // namespace Abx

#endif // _Abx_GraphicsSystem_hpp_
